package com.meiqiang.muxinnetty.controller;


import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.file.LineSeparator;
import com.meiqiang.muxinnetty.utils.FileUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * base controller
 *
 * @author shihuaguo
 * @date 2019/11/11
 **/
@Slf4j
public class BaseController {

    @Value("${file.storage.local.dir:/data/radar}")
    protected String fileStorageDir;



    /**
     * 获取上传文件的保存路径,按照/{配置路径}/{middle}/{日期}/{时间}/{文件名}的路径保存
     */
    protected String getFileStoreDateTimePath(String middle, String fileName) {
        String date = DateUtil.format(new Date(), "yyyy-MM-dd");
        String time = DateUtil.format(new Date(), "HHmmss");
        String filePath = String.format("%s/%s/%s/%s/%s", fileStorageDir, middle, date, time, fileName);
        return Path.of(filePath).toAbsolutePath().toString();
    }

    /**
     * 获取上传文件的保存路径,按照/{配置路径}/{middle}/{日期}/{时间}/{文件名}的路径保存
     */
    protected String getFileStoreDatePath(String middle, String fileName) {
        String date = DateUtil.format(new Date(), "yyyy-MM-dd");
        String filePath = String.format("%s/%s/%s/%s", fileStorageDir, middle, date, fileName);
        return Path.of(filePath).toAbsolutePath().toString();
    }

    /**
     * 上传文件
     *
     * @param file     上传的文件
     * @param filePath 文件保存的文件名
     * @return 成功或失败
     */
    protected String uploadFile(@RequestParam("file") MultipartFile file, String filePath) {
        if (StringUtils.isBlank(filePath)) {
            return "上传文件为空";
        }
        try {
            boolean flag = FileUtil.checkFile(filePath);
            if (flag) {
                file.transferTo(new File(filePath));// 文件写入
                String objectName = resolveObjectName(filePath);
                return objectName;
            } else {
                return "文件上传失败";
            }
        } catch (IOException e) {
            log.error("文件上传失败", e);
            return "文件上传失败";
        }
    }

    protected String resolveObjectName(String filePath) {
        String unixPath = FileUtil.toUnixPath(filePath);
        return unixPath.substring(fileStorageDir.length());
    }

    private String getFileSavePath(MultipartFile file) {
        if (file.isEmpty() || StringUtils.isBlank(file.getOriginalFilename())) {
            return null;
        } else {
            String fileName = file.getOriginalFilename();
            // 获取文件的后缀名
            int dotPos = fileName.lastIndexOf(".");
            String prefixName = fileName.substring(0, dotPos);
            String suffixName = fileName.substring(dotPos);
            String randomName = FileUtil.randomFilename(prefixName) + suffixName;
            log.info("上传的文件名为： {}, 随机生成的文件名: {}", fileName, randomName);

            String date = DateUtil.format(new Date(), "yyyy-MM-dd");
            String objectName = "/upload/" + date + "/" + randomName;
            return fileStorageDir + "/" + objectName;
        }
    }

    protected String uploadFile(@RequestParam("file") MultipartFile file) {
        String filePath = getFileSavePath(file);
        String resolvedPath = Path.of(filePath).toAbsolutePath().toString();
        return uploadFile(file, resolvedPath);
    }

    protected void downloadFile(HttpServletResponse response, File file, String filename) {
        if (file.exists()) {
            response.setContentType("application/octet-stream");
            response.addHeader("Content-Disposition", "attachment;fileName=" + filename);
            try (InputStream is = new FileInputStream(file); OutputStream os = response.getOutputStream()) {
                IOUtils.copy(is, os);
            } catch (IOException e) {
                log.error("file download error", e);
            }
        } else {
            log.error("file {} not exists", file.getAbsolutePath());
        }
    }

    protected void downloadAsCsv(HttpServletResponse response, List<String> lines, String filename) {
        response.setContentType("application/octet-stream");
        response.addHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(filename, StandardCharsets.UTF_8));
        try (OutputStreamWriter osw = new OutputStreamWriter(response.getOutputStream(), StandardCharsets.UTF_8)) {
            osw.write(new String(new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF}));
            for (var s : lines) {
                osw.write(s);
                osw.write(LineSeparator.LINUX.getValue());
            }
        } catch (IOException e) {
            log.error("file download error", e);
        }
    }


}
